import { h, mergeProps, render, resolveComponent } from 'vue'
import { ElTooltip } from 'element-plus'

function isObject(value: any) {
  return value !== null && typeof value === 'object'
}

function mountComponent(component: any, props: (arg0: any, arg1: any) => any) {
  return function (
    el: Element | ShadowRoot,
    binding: { value: { text: any } }
  ) {
    const _props = typeof props === 'function' ? props(el, binding) : props
    const text = binding.value?.text ?? binding.value ?? _props?.text
    const value = isObject(binding.value) ? binding.value : {}

    const children = () => text ?? el.textContent

    const node = h(component, mergeProps(_props, value), children)

    render(node, el)
  }
}

function useDirectiveComponent(component: any, props: any) {
  const concreteComponent =
    typeof component === 'string' ? resolveComponent(component) : component
  const hook = mountComponent(concreteComponent, props)
  return {
    mounted: hook,
    updated: hook,
    unmounted(el: Element | ShadowRoot) {
      render(null, el)
    }
  }
}

const Tooltip = useDirectiveComponent(
  ElTooltip,
  (el: any, binding: { value: any; arg: any }) => {
    return {
      content: typeof binding.value === 'boolean' ? undefined : binding.value,
      placement: binding.arg,
      'virtual-triggering': true,
      'virtual-ref': el
    }
  }
)

export default (app: any) => {
  app.directive('tooltip', Tooltip)
}
